#pragma once

namespace FlooP 
{
	class AST;
	class ASTProcedure;

	class ASTBlock;
	class ASTIf;
	class ASTLoop;
	class ASTMuLoop;
	class ASTAbort;
	class ASTQuit;
	class ASTAssignment;

	class ASTExpression;
	class ASTCompare;
	class ASTBinaryMathOp;
	class ASTCell;
	class ASTProcedureCall;
	class ASTIdentifier;
	class ASTNumber;
	class ASTString;

	class Procedure;

	class VisitorInterface
	{
		public:

		virtual ~VisitorInterface() {}

		virtual void visit (const AST& ast) = 0;
		virtual void visit (const ASTProcedure& procedure) = 0;

		virtual void visit (const ASTBlock& block, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTIf& if_stmt, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTLoop& loop, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTMuLoop& loop, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTAbort& abort, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTQuit& quit, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTAssignment& assign, std::shared_ptr<Procedure> func) = 0;

		virtual void visit (const ASTCompare& expr, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTBinaryMathOp& expr, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTCell& expr, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTProcedureCall& expr, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTIdentifier& expr, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTNumber& num, std::shared_ptr<Procedure> func) = 0;
		virtual void visit (const ASTString& str, std::shared_ptr<Procedure> func) = 0;
	};
}